/*
-----------------
Unicorn Princess
Iteration 1
Rachel J. Morris
www.moosader.com
Dec 2009-Feb 2010
-----------------

LevelManager.cpp
*/

#include "LevelManager.h"

// Singleton intialization accessors
LevelManager& LevelManager::GetInst()
{
    if ( !inst )
        inst = new LevelManager();

    return *inst;
}

LevelManager* LevelManager::InstPtr()
{
    if ( !inst )
        inst = new LevelManager();

    return inst;
}

// Initialization / Constructors / Destructors
LevelManager::LevelManager()
{
    ;
}

void LevelManager::Destroy()
{
    if ( inst != NULL )
        delete [] inst;
}

void LevelManager::Init( string& lvlDir )
{
    /* Initialize the enemies on level 0 */
    LoadLevel( lvlDir, 0 );
}

void LevelManager::LoadLevel( string& lvlDir, int lvl )
{
    /*
        Initialize the enemies, loading in the level file and placing them
        at their starting points, with their enemy type ID
    */

    // Temp: Clean up

    if ( CharacterManager::GetInst().enemy != NULL )
    {
        delete [] CharacterManager::GetInst().enemy;
        CharacterManager::GetInst().enemy = NULL;   // initialize enemy array
        CharacterManager::GetInst().EnemyCount( 0 );
    }

    // Load in map
    ifstream infile;
    string levelname = lvlDir;
    levelname += "lv_";
    string buffer;
    buffer = IntToString( lvl );
    //itoa( lvl, buf, 10 ); // Convert integer to character array, integer lvl, character buf, base 10 number
    levelname += buffer;
    levelname += ".upm";

    infile.open( levelname.c_str() );

    cout<<"Loading level "<<levelname<<"...";

    if ( infile.fail() )
    {
        infile.close();
        // Write in log that we couldn't open this level file
        cerr<<"Error "<<FILEPATH_ERROR<<": Error opening '"<<levelname<<"'"<<endl;
        cout<<" Fail"<<endl;
        exit( FILEPATH_ERROR );
    }
    // else ...
    cout<<" Opened, loading enemies... ";

    string temp;
    string type = "-1";
    int x = -1, y = -1;
    bool readFile = true;
    while ( infile>>temp && readFile )
    {
        if ( temp == "level_name" )     { ; } // Save for later
        else if ( temp == "type" )      { infile>>type; }       // Store the enemy type temporarily
        else if ( temp == "x" )         { infile>>x; }          // Store the x coordinate temporarily
        else if ( temp == "y" )         { infile>>y; }          // Store the x coordinate temporarily
        else if ( temp == "end_level" ) { readFile = false; }   // Stop reading map file

        else if ( temp == "next_level_x" )
        {
            infile>>warpPoint;
        }

        else if ( temp == "bg_image" )
        {
            // Set the level's background image
            infile>>temp;
            ImageManager::GetInst().SetBackgroundImage( temp );
        }

        else if ( temp == "end_enemy" )
        {
            // Check to see if all values are populated
            if ( type == "-1" || x == -1 || y == -1 )
            {
                cerr<<"Error "<<MISSING_ENEMY_INFO<<": Error loading in enemy, missing info.  Skipping."<<endl;
            }
            else
            {
                // Create enemy
                CharacterManager::GetInst().CreateEnemy( type, x, y );
            }
            // Reset values
            x = y = -1;
            type = "-1";
        }
    }

    cout<<" Success!"<<endl;

    ImageManager::GetInst().ResetLevelVariables();

    infile.close();

    // Tell program to draw the level name on the screen
    ImageManager::GetInst().ShowTitle( lvl );
}

void LevelManager::WarpPoint( int val ) { warpPoint = val; }

int LevelManager::WarpPoint() { return  warpPoint; }

void LevelManager::CheckIfWarpReached()
{
    if ( ImageManager::GetInst().AbsScroll() >= warpPoint )
    {
        cout<<"WARP REACHED"<<endl;
        LoadLevel( GameSys::GetInst().LvlDirPtr(), 1 );
        ImageManager::GetInst().ResetLevelVariables();
        CharacterManager::GetInst().player.ReInit();
    }
}


